/******************************************************************************
 * Copyright (C) 2016 Wuhan Water Elephant Co.Ltd All Rights Reserved. 
 * 本软件为武汉水象科技有限公司开发研制。 未经本公司正式书面同意，其他任何个人、
 * 团体不得使用、复制、修改或发布本软件.
 *****************************************************************************/
package com.sxfq.loansupermarket.common.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

/**
 * 
 * 
 * Module:
 * 
 * BeanUtil.java
 * 
 * @author 毛恩奇
 * @since JDK 1.8
 * @version 1.0
 * @description: <描述>
 */
public class BeanUtil {
	/**
	 * 获取JavaBean的字段对象集合
	 * 
	 * @param clazz JavaBean字节码对象
	 * @return
	 */
	public static <T> List<Field> getFieldList(Class<T> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		List<Field> filedList = null;
		if (fields != null && fields.length > 0) {
			filedList = new ArrayList<Field>();
			for (Field field : fields) {
				filedList.add(field);
			}
		}
		return filedList;
	}

	/**
	 * 获取JavaBean的字段名称集合
	 * 
	 * @param clazz JavaBean字节码对象
	 * @return
	 */
	public static <T> List<String> getFieldNameList(Class<T> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		List<String> filedNameList = null;
		if (fields != null && fields.length > 0) {
			filedNameList = new ArrayList<String>();
			for (Field field : fields) {
				filedNameList.add(field.getName());
			}
		}
		return filedNameList;
	}

	/**
	 * 获取JavaBean的字段名称集合，排除不需要获取的字段名
	 * 
	 * @param clazz JavaBean字节码对象
	 * @param exFieldNameList 排除指定字段名
	 * @return
	 */
	public static <T> List<String> getFieldNameList(Class<T> clazz, List<String> exFieldNameList) {
		Field[] fields = clazz.getDeclaredFields();
		List<String> filedNameList = null;
		if (fields != null && fields.length > 0) {
			filedNameList = new ArrayList<String>();
			for (Field field : fields) {
				if (exFieldNameList != null && !exFieldNameList.isEmpty()) {
					if (!exFieldNameList.contains(field.getName())) {
						filedNameList.add(field.getName());
					}
				} else {
					filedNameList.add(field.getName());
				}
			}
		}
		return filedNameList;
	}

	/**
	 * 获取JavaBean的字段名称集合，排除不需要获取的字段名
	 * 
	 * @param clazz JavaBean字节码对象
	 * @param exFieldNameList 排除指定字段名
	 * @param customFieldNameList 自定义对象字段名,如user.name
	 * @return
	 */
	public static <T> List<String> getAllFieldNameList(Class<T> clazz, List<String> exFieldNameList,
			List<String> customFieldNameList) {
		Field[] fields = clazz.getDeclaredFields();
		List<String> filedNameList = null;
		if (fields != null && fields.length > 0) {
			filedNameList = new ArrayList<String>();
			for (Field field : fields) {
				String canonicalName = field.getType().getCanonicalName();
				if (canonicalName.contains("java.lang") || canonicalName.equals("long")) {
					if (exFieldNameList != null && !exFieldNameList.isEmpty()) {
						if (!exFieldNameList.contains(field.getName())) {
							filedNameList.add(field.getName());
						}
					} else {
						filedNameList.add(field.getName());
					}
				} else {// 自定义对象作为字段
					Field[] innerFields = field.getType().getDeclaredFields();
					if (customFieldNameList != null && !customFieldNameList.isEmpty() && innerFields != null
							&& innerFields.length > 0) {
						for (Field innerField : innerFields) {
							String innerFieldName = field.getName() + "." + innerField.getName();
							if (customFieldNameList.contains(innerFieldName)) {
								filedNameList.add(innerFieldName);
							}
						}
					} else if (customFieldNameList == null || customFieldNameList.isEmpty()) {
						filedNameList.add(field.getName());
					}
				}
			}
		}
		return filedNameList;
	}

	/**
	 * 判断JavaBean中是否有指定字段名
	 * 
	 * @param clazz JavaBean字节码对象
	 * @param fieldName 判断是否包含的字段名
	 * @return
	 */
	public static <T> boolean hasField(Class<T> clazz, String fieldName) {
		boolean flag = false;
		List<Field> fieldList = getFieldList(clazz);
		if (fieldList != null && !fieldList.isEmpty() && fieldName != null && fieldName.trim() != "") {
			for (Field field : fieldList) {
				if (fieldName.equals(field.getName())) {
					flag = true;
					break;
				}
			}
		}
		return flag;
	}

	/**
	 * 通过字段名获取Field对象，没有该字段则返回null
	 * 
	 * @param clazz
	 * @param fieldName
	 * @return
	 */
	public static <T> Field getFieldByFieldName(Class<T> clazz, String fieldName) {
		Field field = null;
		try {
			field = clazz.getDeclaredField(fieldName);
		} catch (Exception e) {
			// e.printStackTrace();
		}
		return field;
	}

	/**
	 * 实现一个通用的方法 为任意的一个javabean的任意属性赋任意值
	 * 
	 * @param bean
	 * @param fieldName
	 * @param value
	 */
	public static void setProperty(Object bean, String fieldName, Object value) {
		try {
			if (hasField(bean.getClass(), fieldName)) {
				// 创建属性描述器
				PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, bean.getClass());
				// 获得 写方法
				Method writeMethod = descriptor.getWriteMethod();
				// 调用 写方法
				writeMethod.invoke(bean, value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Object getProperty(Object bean, String fieldName) {
		Object value = null;
		try {
			if (hasField(bean.getClass(), fieldName)) {
				// 创建属性描述器
				PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, bean.getClass());
				// 获得读方法
				Method readMethod = descriptor.getReadMethod();
				// 调用读方法
				value = readMethod.invoke(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return value;
	}

	public static <T> String beanToXml(T t, List<String> exFieldNameList) {
		Class<? extends Object> clazz = t.getClass();
		List<String> fieldNameList = getFieldNameList(clazz, exFieldNameList);
		String className = clazz.getSimpleName();
		StringBuilder sb = new StringBuilder();
		sb.append("<" + className + ">");
		for (String fieldName : fieldNameList) {
			Object value = getProperty(t, fieldName);
			sb.append("<" + fieldName + ">");
			sb.append(value == null ? "" : value);
			sb.append("</" + fieldName + ">");
		}
		sb.append("</" + className + ">");
		return sb.toString();
	}

	public static <T> String arrayToXml(T[] tArray, List<String> exFieldNameList) {
		StringBuilder sb = new StringBuilder();
		for (T t : tArray) {
			sb.append(beanToXml(t, exFieldNameList));
		}
		return sb.toString();
	}

	/**
	 * 将起源bean的非空的属性值复制到目标bean中
	 * 
	 * @author maomao
	 * @date 2015年7月14日 下午2:06:19
	 * @param dest 目标bean
	 * @param orig 起源bean
	 */
	public static <T> void copyNotEmptyProperties(T dest, T orig) {
		List<String> exFildNameList = new ArrayList<String>();
		exFildNameList.add("serialVersionUID");
		copyNotEmptyProperties(dest, orig, exFildNameList);
	}

	/**
	 * 将起源bean的非空的属性值复制到目标bean中
	 * 
	 * @author maomao
	 * @date 2015年7月14日 下午2:06:19
	 * @param dest 目标bean
	 * @param orig 起源bean
	 */
	public static <T> void copyNotEmptyProperties(T dest, T orig, List<String> exFildNameList) {
		List<String> destFieldNameList = getFieldNameList(dest.getClass());
		for (String destFieldName : destFieldNameList) {
			if (!containsIgnoreCase(exFildNameList, destFieldName)) {
				Object origFieldValue = getProperty(orig, destFieldName);
				if (origFieldValue != null) {
					setProperty(dest, destFieldName, origFieldValue);
				}
			}
		}
	}

	public static boolean containsIgnoreCase(List<String> list, String str) {
		boolean bool = false;
		if (list != null && !list.isEmpty() && StringUtils.isNotEmpty(str)) {
			for (String temp : list) {
				if (str.equalsIgnoreCase(temp)) {
					bool = true;
					break;
				}
			}
		}
		return bool;
	}
}